package org.rency.mq.activemq.listener.factory;

import org.rency.mq.activemq.listener.handler.impl.AbstractMessageHandler;

import javax.jms.ConnectionFactory;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class MultipleMessageHandlerContainer {
    public List<AbstractMessageListenerContainer>           messageListenerContainers       = new LinkedList<AbstractMessageListenerContainer>();
    private List<AbstractMessageHandler>                    messageHandlers;

    private ConnectionFactory                               connectionFactory;
    private boolean                                         sessionAware = false;
    private String                                          sessionAcknowledgeModeName = "AUTO_ACKNOWLEDGE";
    private Map<Integer, List<AbstractMessageListenerContainer>> actionIdMessageHandlers         = new HashMap<Integer, List<AbstractMessageListenerContainer>>();

    private AbstractMessageListenerContainerFactory         messageListenerContainerFactory = new DefaultMessageListenerContainerFactory();

    public List<AbstractMessageHandler> getMessageHandlers() {
        return messageHandlers;
    }

    public void setMessageHandlers(List<AbstractMessageHandler> messageHandlers) {
        this.messageHandlers = messageHandlers;
    }

    public void addMessageHandler(AbstractMessageHandler messageHandler) {
        if (messageHandlers == null || messageHandlers.isEmpty()) {
            messageHandlers = new LinkedList<AbstractMessageHandler>();
        }

        messageHandlers.add(messageHandler);
    }

    public ConnectionFactory getConnectionFactory() {
        return connectionFactory;
    }

    public void setConnectionFactory(ConnectionFactory connectionFactory) {
        this.connectionFactory = connectionFactory;
    }

    public void init() {
        if (messageHandlers == null || messageHandlers.isEmpty()) {
            return;
        }
        for (AbstractMessageHandler messageHandler : messageHandlers) {
            AbstractMessageListenerContainer listenerContainer = buildMessageListener(messageHandler);
            messageListenerContainers.add(listenerContainer);
            if (messageHandler.getActionId() > 0) {
                addActionIdMessageHandler(messageHandler.getActionId(), listenerContainer);
            }
        }
        fireStartListeningEvent();
    }

    public void destroy() {
        if (messageHandlers == null || messageHandlers.isEmpty()) {
            return;
        }
        fireStopListeningEvent();
    }

    private void addActionIdMessageHandler(int actionId, AbstractMessageListenerContainer messageListener) {
        if (actionId <= 0) {
            return;
        }
        List<AbstractMessageListenerContainer> listeners = actionIdMessageHandlers.get(actionId);
        if (listeners == null || listeners.isEmpty()) {
            return;
        }
        listeners.add(messageListener);
    }

    private AbstractMessageListenerContainer buildMessageListener(AbstractMessageHandler messageHandler) {
        AbstractMessageListenerContainer listenerContainer = messageListenerContainerFactory.createMessageListenerContainer();
        listenerContainer.setConnectionFactory(connectionFactory);
        listenerContainer.setMessageHandler(messageHandler);
        listenerContainer.setSessionAware(this.sessionAware);
        listenerContainer.setSessionAcknowledgeModeName(sessionAcknowledgeModeName);
        return listenerContainer;
    }

    public void fireStartListeningEvent() {
        for (AbstractMessageListenerContainer listenerContainer : messageListenerContainers) {
            listenerContainer.startContainer();
        }
    }

    public void fireStartListeningEvent(int actionId) {
        List<AbstractMessageListenerContainer> listenerContainers = actionIdMessageHandlers
            .get(actionId);

        for (AbstractMessageListenerContainer listenerContainer : listenerContainers) {
            listenerContainer.startContainer();
        }
    }

    public void fireStopListeningEvent() {
        for (AbstractMessageListenerContainer listenerContainer : messageListenerContainers) {
            listenerContainer.stopContainer();
        }
    }

    public void fireStopListeningEvent(int actionId) {
        List<AbstractMessageListenerContainer> listenerContainers = actionIdMessageHandlers
            .get(actionId);

        for (AbstractMessageListenerContainer listenerContainer : listenerContainers) {
            listenerContainer.stopContainer();
        }
    }

    public AbstractMessageListenerContainerFactory getMessageListenerContainerFactory() {
        return messageListenerContainerFactory;
    }

    public void setMessageListenerContainerFactory(AbstractMessageListenerContainerFactory messageListenerContainerFactory) {
        this.messageListenerContainerFactory = messageListenerContainerFactory;
    }


    public boolean isSessionAware() {
        return sessionAware;
    }

    public void setSessionAware(boolean sessionAware) {
        this.sessionAware = sessionAware;
    }

    public String getSessionAcknowledgeModeName() {
        return sessionAcknowledgeModeName;
    }

    public void setSessionAcknowledgeModeName(String sessionAcknowledgeModeName) {
        this.sessionAcknowledgeModeName = sessionAcknowledgeModeName;
    }
}
